#ifndef T_AV_PACKET_H
#define T_AV_PACKET_H

#include "t_av_common.h"

#include <QtCore>

class T_AV_Packet;
struct T_Box_Stream_Info;
class T_Box_Player_Context;

class T_AV_Packet : public QObject
{
    Q_OBJECT
protected:
    AVPacket m_av_packet;
    int m_timing;
public:
    int m_frame_no;
    T_Box_Player_Context *m_player_ctx;
    AVFormatContext *m_format_ctx;
    int m_stream_index;
    AVStream *m_stream;
    AVCodecContext *m_codec_ctx;
    //AVPacket m_av_packet;
    ~T_AV_Packet()
    {
        ::av_free_packet(&m_av_packet);
    }
    //[decodeAudio()]
    QByteArray decodeAudio();
    //[decodeVideo()]
    bool decodeVideo(SDL_Overlay *a_overlay);
    //[timing()] returns packets pts in milliseconds
    int timing()
    {
        return m_timing;
    }
protected:
    friend class T_Box_Player_Context;
    explicit T_AV_Packet(T_Box_Player_Context *a_player_ctx, AVPacket &a_av_packet);
};

class T_AV_Packet_Queue : public QObject
{
    Q_OBJECT
protected:
    QMutex m_mutex;
    QQueue<T_AV_Packet *> packet_queue;
    int m_enqueue_count;
public:
    explicit T_AV_Packet_Queue()
        : m_mutex(QMutex::Recursive)
        , m_enqueue_count(0)
    {
    }
    ~T_AV_Packet_Queue()
    {
    }
    QMutex *mutex()
    {
        return &this->m_mutex;
    }
    int size()
    {
        QMutexLocker v_lock(&m_mutex);
        Q_UNUSED(v_lock);
        return packet_queue.size();
    }
    void enqueue(T_AV_Packet *a_av_packet)
    {
        QMutexLocker v_lock(&m_mutex);
        Q_UNUSED(v_lock);
        a_av_packet->m_frame_no = m_enqueue_count++;
        packet_queue.enqueue(a_av_packet);
    }
    T_AV_Packet *dequeue()
    {
        QMutexLocker v_lock(&m_mutex);
        Q_UNUSED(v_lock);
        if(packet_queue.size()==0) return NULL;
        return packet_queue.dequeue();
    }
    T_AV_Packet *head()
    {
        QMutexLocker v_lock(&m_mutex);
        Q_UNUSED(v_lock);
        if(packet_queue.size()==0) return NULL;
        return packet_queue.head();
    }
    T_AV_Packet *last()
    {
        QMutexLocker v_lock(&m_mutex);
        Q_UNUSED(v_lock);
        if(packet_queue.size()==0) return NULL;
        return packet_queue.last();
    }
};

#endif // T_AV_PACKET_H
